package org.fmi.lje.graphics.model;

import java.util.ArrayList;
import java.util.List;

public class Relationship extends Shape {

	protected Clazz from;
	protected Clazz to;

	protected Relationship(Clazz from, Clazz to) {
		super(0, 0, 0, 0, null);

		this.from = from;
		this.to = to;

		this.setParent(from.getParent());
	}

	public Clazz getTo() {
		return to;
	}

	public Clazz getFrom() {
		return from;
	}

	@Override
	public String toString() {
		return "[" + this.getClass().toString() + "] [ from: " + from + "] [ to: " + to + "]";
	}

	private float mY() {
		float fx = from.getX() + from.getWidth() / 2;
		float fy = from.getY() + from.getHeight() / 2;

		float tx = to.getX() + to.getWidth() / 2;
		float ty = to.getY() + to.getHeight() / 2;

		return (tx - fx) / (ty - fy);
	}

	private int fY(int x) {
		float fx = from.getX() + from.getWidth() / 2;
		float fy = from.getY() + from.getHeight() / 2;

		return Math.round(mY() * x - mY() * fy + fx);
	}

	private float mX() {
		return 1 / mY();
	}

	private int fX(int x) {
		float fx = from.getX() + from.getWidth() / 2;
		float fy = from.getY() + from.getHeight() / 2;

		return Math.round(mX() * x - mX() * fx + fy);
	}

	private List<Position> getIntersection(Shape shape) {
		List<Position> positions = new ArrayList<Position>();

		int x = 0;
		int y = 0;

		x = shape.getX();
		y = fX(x);

		if (shape.getY() - 5 <= y && y <= shape.getY() + shape.getHeight() + 5) {
			positions.add(new Position(x, y));
		}

		x = shape.getX() + shape.getWidth();
		y = fX(x);

		if (shape.getY() - 5 <= y && y <= shape.getY() + shape.getHeight() + 5) {
			positions.add(new Position(x, y));
		}

		y = shape.getY();
		x = fY(y);

		if (shape.getX() - 5 <= x && x <= shape.getX() + shape.getWidth() + 5) {
			positions.add(new Position(x, y));
		}

		y = shape.getY() + shape.getHeight();
		x = fY(y);

		if (shape.getX() - 5 <= x && x <= shape.getX() + shape.getWidth() + 5) {
			positions.add(new Position(x, y));
		}

		return positions;
	}

	@Override
	public void draw() {
		super.draw();

		List<Position> positions1 = getIntersection(from);
		List<Position> positions2 = getIntersection(to);

		System.out.println(from);
		System.out.println(to);
		System.out.println(positions1);
		System.out.println(positions2);
		
		int fx = 0;
		int fy = 0;
		int tx = 0;
		int ty = 0;

		float min = Float.MAX_VALUE;

		for (Position pF : positions1) {
			for (Position pT : positions2) {
				float distance = (pF.getX() - pT.getX()) * (pF.getX() - pT.getX()) + (pT.getY() - pT.getY()) * (pT.getY() - pT.getY());

				if (distance < min) {
					fx = pF.getX();
					fy = pF.getY();

					tx = pT.getX();
					ty = pT.getY();
					
					min = distance;
				}
			}
		}

		getGraphics().drawLine(fx, fy, tx, ty);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((from == null) ? 0 : from.hashCode());
		result = prime * result + ((to == null) ? 0 : to.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Relationship other = (Relationship) obj;
		if (from == null) {
			if (other.from != null)
				return false;
		} else if (!from.equals(other.from))
			return false;
		if (to == null) {
			if (other.to != null)
				return false;
		} else if (!to.equals(other.to))
			return false;
		return true;
	};
}
